# jwt_custom.py
import base64

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import check_password
from rest_framework.exceptions import AuthenticationFailed

from .models import user_login


# 使用jwt的登录接口，自定义方式认证，request一直是空，取不到内容，如果有验证码等其他要校验的呢？
# 为啥要自定义认证类，因为jwt默认是校验auth_user表的用户名密码
class UserAuthBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):

        try:
            # LbUserInfo为自定义的用户表
            user = user_login.objects.filter(username=request.POST.get("userid"),
                                             user_passwd=request.POST.get("passwd"))
            # 密码使用base64解码后使用
            print("-----这是我自定义的JWT验证--------", user)
            if user:
                return user
        except:
            raise AuthenticationFailed("没有查找到用户")

    def authenticate_header(self, request):
        pass


# 重写drf-jwt登录视图，构造响应内容
def jwt_response_payload_handler(token, user=None, request=None):
    return {
        "token": token,
        "username": user.user_name,
        "status": 200
    }


# 自定义认证类
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.settings import api_settings

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
import jwt


# token验证
class JwtAuthentication(BaseAuthentication):
    def authenticate(self, request):

        # 第一步：取出前端传入的token串（从请求头的token中取出）
        # 从请求头获取
        jwt_value = request.META.get('HTTP_TOKEN')
        if request.method == "GET":
            # print(request.GET)
            # jwt_value = request.GET.get('token')
            return

        if jwt_value:
            print("这是我自定义的您携带了token")
            # 验证token是否合法
            try:
                # 通过token，得到payload，在得到的过程中会校验，是否过期，是否被篡改
                payload = jwt_decode_handler(jwt_value)
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('签名过期')
            except jwt.DecodeError:
                raise AuthenticationFailed('签名验证失败')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('未知错误')

            # print(payload)
            # 有没有问题？每次都要去数据库查用户，效率低
            # 优先用这种
            user = user_login.objects.get(id=payload['user_id'])

            # 不需要查数据库，效率高，存在缺陷，
            # user=User(id=payload['user_id'],username=payload['username'])
            return user, jwt_value

        else:
            # 没带token串，没登录
            print("这是我自定义的您没有携带token")
            raise AuthenticationFailed('您没有携带token')
